package com.kcs.fxmargin.service;

import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.List;
import java.util.ResourceBundle;

import org.apache.log4j.Logger;

import com.kcs.common.utils.Based64Utils;
import com.kcs.common.utils.ConnectionUtils;
import com.kcs.common.utils.Constant;
import com.kcs.common.utils.PropsUtils;
import com.kcs.fxmargin.bo.FXEndOfDayBO;
import com.kcs.fxmargin.bo.InquiryAccountWSBO;
import com.kcs.fxmargin.dao.FXEndOfDayDAO;
import com.kcs.fxmargin.model.MCustInfo;
import com.kcs.fxmargin.model.TDeals;
import com.kcs.fxmargin.ws.InquiryAccountWS;

public class FXEndOfDayService {

	private Logger log 		= Logger.getLogger(Constant.LOG_FX);
	private Logger logCbs 	= Logger.getLogger(Constant.LOG_CBS);
	
	public void runEndOfDay()throws Exception{
		FXEndOfDayDAO dao = null;
		FXEndOfDayBO bo = null;
		Connection conn = null;
		InquiryAccountWS ws = null;
		InquiryAccountWSBO wsBo = null;
		List<MCustInfo> mCustInfoList = null;
		MCustInfo mCustInfo = null;
		List<TDeals> tDealsList = null;
		TDeals tDeals = null;
		boolean result = false;
		DealsService dcWs = null;
		boolean firstDeleteTDealsHistory = true;
		ResourceBundle prop = null;
		String onlineFlag = null;
		
		try{
			
			dao = new FXEndOfDayDAO();
			bo = new FXEndOfDayBO();
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO);

			//-- Get m_cust_info
			bo = dao.getMCustInfoList(bo,conn);
			mCustInfoList = bo.getmCustInfoList();
			System.out.println("Get m_cust_info : size = "+(mCustInfoList==null?"null":mCustInfoList.size()));
			
			if(mCustInfoList != null){
				
				ws = new InquiryAccountWS();
				dcWs = new DealsService();
			
				//-- Get online_flag
				//bo = dao.getOnlineFlag(bo,conn);
				prop = PropsUtils.getProps(Constant.PROP_CONFIG_SYSTEM);
				onlineFlag = prop.getObject("online_flag").toString();
				bo.setOnlineFlag(onlineFlag);
				
				System.out.println("Get online_flag: "+bo.getOnlineFlag());
				
				//-- Set AsOfDate
				bo.setAsOfDate(getAsOfDateWithConfig(bo.getOnlineFlag()));
				System.out.println("Set AsOfDate: "+bo.getAsOfDate());
				
				//-- Call WS from DealCenter
				System.out.println(">> Call WS DealCenter");
				dcWs.dealCenterWithConnection(conn);
				System.out.println(">> DealCenter Success!");
				System.out.println();
			
				//==== LOOP ====//
				System.out.println(">>>>>>> START LOOP : size= "+mCustInfoList.size());
				for(int i=0; i<mCustInfoList.size(); i++){
					System.out.println(">>> ["+i+"] >>>");
					mCustInfo = mCustInfoList.get(i);
					
					//-- SPCallMarginLimit
					System.out.println(">> Call SPCallMarginLimit");
					bo.setCifNo(mCustInfo.getCifNo());
					bo = dao.callMarginLimit(bo, conn);
					System.out.println(">> SPCallMarginLimit Success! : marginLimit: "+bo.getMarginLimit());
					System.out.println();

					//-- Call WS InquiryAccountDetail
					System.out.println(">> Call WS InquiryAccountDetail");
					wsBo = new InquiryAccountWSBO();
					wsBo.setCifNo(mCustInfo.getCifNo());
					wsBo.setMarginAccNo(mCustInfo.getMarginAccNo());
					
					System.out.println("> cifNo: "+wsBo.getCifNo());
					System.out.println("> marginAccNo: "+wsBo.getMarginAccNo());
					
					ws.inquiryAccountDetail(wsBo);
					System.out.println(">> InquiryAccountDetail Success!");
					System.out.println();
					
					//=== INSERT TDEALS ===//
					
					System.out.println(">> Get t_deals List");
					bo.setCifNo(mCustInfo.getCifNo());
					bo = dao.getTDealsList(bo, conn);
					tDealsList = bo.gettDealsList();
					System.out.println(">> Success! : t_deals size: "+(tDealsList==null?"null":tDealsList.size()));
					System.out.println();
					
					if(tDealsList != null){
						//-- Insert TDeals History
						if(firstDeleteTDealsHistory){
							System.out.println(">> Delete t_deals_history");
							result = dao.deleteTDealsHistory(bo.getAsOfDate(), conn);
							System.out.println(">> Delete t_deals_history : result : "+result);
							System.out.println();
							
							firstDeleteTDealsHistory = false;
						}
						
						System.out.println("+++++++++ LOOP t_deals_history : size= "+tDealsList.size());
						for(int j=0; j<tDealsList.size(); j++){
							System.out.println("+++ ["+j+"] +++");
							tDeals = tDealsList.get(j);

							System.out.println(">> Insert t_deals_history");
							result = dao.insertTDealsHistory(tDeals.getId(), bo.getAsOfDate(), conn);
							System.out.println(">> Insert t_deals_history : result : "+result);
							System.out.println();
						}
						System.out.println("+++++++++++++++");
					}
					
					
				}	
				System.out.println(">>>>>>>>>>>>>>>>>>>>");
				
				//-- Delete t_deals
				System.out.println("Delete TDeals? : "+!bo.getOnlineFlag().equalsIgnoreCase("Y"));
				//***if(!bo.getOnlineFlag().equalsIgnoreCase("Y")){
					dao.deleteTDeals(bo.getAsOfDate(), conn);
					System.out.println("Delete t_deals : result : success!");
				//***}
				
				
				conn.commit();
			}
			
		}catch(Exception e){
			if(conn != null){
				conn.rollback();
			}
			throw e;
		}finally{
			if(conn != null){
				try{
					conn.close();
				}catch(Exception ex){
					throw ex;
				}
			}
		}
		
	}
	
	public String getAsOfDateWithConfig(String onlineFlag)throws Exception{
		Calendar c = Calendar.getInstance();
		
		if(!onlineFlag.equalsIgnoreCase("Y")){
			c.add(Calendar.DATE, -1);
		}
		
		return c.get(Calendar.YEAR)+"-"+(c.get(Calendar.MONTH)+1)+"-"+c.get(Calendar.DATE);
	}
	
	public void callDealCenter(){
		DealsService dcWs = new DealsService();
		try {
			
			System.out.println(">> Call WS DealCenter");
			dcWs.dealCenter();
			System.out.println(">> DealCenter Success!");
			System.out.println();
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public void callArchiveData(FXEndOfDayBO bo)throws Exception{
		FXEndOfDayDAO dao = null;
		Connection conn = null;
		
		try{
			
			dao = new FXEndOfDayDAO();
			conn = ConnectionUtils.getConnection(Constant.MSSQL, Constant.TO);
			
			dao.callArchiveData(bo, conn);
				
			conn.commit();
			
		}catch(Exception e){
			if(conn != null){
				conn.rollback();
			}
			throw e;
		}finally{
			if(conn != null){
				try{
					conn.close();
				}catch(Exception ex){
					throw ex;
				}
			}
		}
	}
	
	public static void main(String[] args){
		FXEndOfDayService fx = new FXEndOfDayService();
		try {
			fx.callDealCenter();
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public boolean testConnectionCBS() throws Exception {
		boolean connect = false;
		
		try{
			InquiryAccountWS ws = new InquiryAccountWS();
			
			InquiryAccountWSBO bo = new InquiryAccountWSBO();
			
			bo.setCifNo("1");
			bo.setMarginAccNo("");
			bo.setOutsBal(new BigDecimal(0));
			bo.setUser("");
			
			ws.inquiryAccountDetail(bo);
			ws.inquiryAccountStatement(bo);
			connect = true;
		} catch (Exception e) {
			logCbs.error(e);
			throw e;
		}
		
		return connect;
	}
	
	public boolean testConnectionOracle() throws Exception {
		boolean connect = false;
		Connection conn = null;
		
		try{
			conn = getConnection(Constant.ORACLE, Constant.FROM);
			if(conn != null) connect = true;
		} catch (Exception e){
			connect = false;
			log.error(e);
			throw e;
		} finally {
			if(conn != null) conn.close();
		}
		
		return connect;
	}
	
	public Connection getConnection(String base, String from_to) throws Exception{
		Connection connection = null;
        String driver = PropsUtils.getMessage(Constant.PROP_DATABASE, "db."+ base +".driver");
        String url = PropsUtils.getMessage(Constant.PROP_DATABASE, "db."+ base +".url."+ from_to);
        String username = Based64Utils.base64decode(PropsUtils.getMessage(Constant.PROP_DATABASE, "db."+ base +".login." + from_to ));
        String password = Based64Utils.base64decode(PropsUtils.getMessage(Constant.PROP_DATABASE, "db."+ base +".encpassword." + from_to));

        try {
            // Load the JDBC driver
            Class.forName(driver);
            
            // Create a connection to the database
            System.setProperty("NLS_LANG", "AMERICAN_AMERICA.TH8TISASCII");
            connection = DriverManager.getConnection(url, username, password);

            connection.setAutoCommit(false);

        } catch (ClassNotFoundException e) {
        	throw e;
        } catch (SQLException e) {
        	throw e;
        }
        return connection;
    }

}
